; int generar_codificacion ( unsigned char *src_buf, unsigned int src_size,
;		unsigned char *dst_buf, unsigned int dst_size, codigo_t *tabla_codigos )

%include "macros.mac"

extern printf
extern stdout ;para el fflush
extern fflush ;para que el printf imprima bien durante un ciclo

%define ptr_src_buf			[ebp + 8]
%define src_size			[ebp + 12]
%define ptr_dst_buf			[ebp + 16]
%define dst_size			[ebp + 20]
%define ptr_tabla_codigos	[ebp + 24]


%define codigot_temp_cod_rev	[ebp - 4]
%define codigot_temp_long_cod	[ebp - 8]
%define codigot_temp_valido		[ebp - 12]
%define bits_agregados					[ebp - 16]
%define byte_a_escribir			[ebp - 17]
%define porcentaje ebp-21

%define offset_cod_rev	4
%define offset_long_cod	8
%define offset_valido	12

%define sizeof_codigo_t 16

global generar_codificacion

section .data
	_msj: db 13,"%d%% comprimido.",0
	_new_line: db 10,0

section .text

generar_codificacion:
				convencion_C 21
				
				mov byte_a_escribir, byte 0	; byte a escribir = 0 
				
				xor ecx, ecx			; i = 0
				xor edx,edx
				mov bits_agregados, dword 0
				mov dl, byte_a_escribir
				mov dword [porcentaje], 0
; Ciclo For: recorro cada byte nro i			
	.cicloFor_src:
					
					;imprimo el porcentaje!
					pusha
					xor edx,edx
					;total / 100
					mov eax, src_size
					mov esi, 100
					div esi
					cmp eax,0
					je .fin_porcentaje
					mov esi,ecx
					
					;contador % total (cuando divido, en edx me pone el remainder)
					;tengo q hacer un swap con los registros.. =S
					;quien dijo que necesito una var temporal para hacer el swap??? >=D
					;jajaja  http://en.wikipedia.org/wiki/XOR_swap_algorithm
					;esto del swap quedo desde el mismo algoritmo en la parte de
					;descomprimir.. por ahi no es necesario aca, pero funciona
					xor esi,eax
					xor eax,esi
					xor esi,eax
					div esi
					;en edx = i % (cant_codificaciones/100)
					cmp edx, 0
					jne .fin_porcentaje
					;porcentaje++
					inc dword [porcentaje]
					
					
					push dword [porcentaje]
					push _msj
					call printf
					add esp,8

					;esto es cierto algo para que me imprima lindo el porcentaje ;)
					push dword [stdout]
					call fflush
					add esp,4

						

					.fin_porcentaje:
					popa
					;fin imprimir porcentaje

	
				mov esi, ptr_src_buf
				
				;obtengo el caracter de la posicion i de src_buf
				xor eax, eax
				mov al, byte [esi + ecx]	; 	eax = src_buf[i]
										
				
				; codigo_t  temp = tabla_codigos[ src_buf[i] ]
				mov ebx, ptr_tabla_codigos
				shl eax, 4 ;i*16
				add eax, ebx
							
				mov edi, dword [eax  + offset_cod_rev]
				mov codigot_temp_cod_rev, edi
				
				mov edi, dword [eax + offset_long_cod]
				mov codigot_temp_long_cod, edi
				
				mov edi, dword [eax + offset_valido]
				mov codigot_temp_valido, edi
				
				
				
				; Si no es valido, Mensaje de error
				
				xor edi,edi    ; j = 0
				
				cmp codigot_temp_valido, dword 1
				je .codificar
				jmp .error_tabla
				
				
	.codificar:	;ciclo j < long_codigo
			mov eax, codigot_temp_cod_rev
			and eax, 1  ; rev % 2

			cmp bits_agregados, dword 7
			jnz .seguir
				;bits_agregados != 7
				shl dl, 1 ;byte_a_escribir << 1;
				add dl, al
				mov ebx, ptr_dst_buf

				mov [ebx], dl
				inc dword ptr_dst_buf
				mov bits_agregados, dword 0
				xor edx,edx
				jmp .seguir_ciclo
			.seguir:
				;bits_agregados != 7
				shl dl, 1 ;byte_a_escribir << 1;
				add dl, al
				inc dword bits_agregados

		.seguir_ciclo:
			shr dword codigot_temp_cod_rev,1
			inc edi
			cmp edi, codigot_temp_long_cod
			jnz .codificar

	inc ecx
	cmp ecx, src_size
	jnz .cicloFor_src

	push _new_line
	call printf
	add esp,4

	mov eax,1  ;no error
	cmp bits_agregados, dword 7
	jz .fin_gc
		dec dword bits_agregados
		mov ecx,bits_agregados
		.ciclo_shr:
			shl dl,1
			inc ecx
			cmp ecx, 7
			jnz .ciclo_shr
		mov ebx, ptr_dst_buf
		mov [ebx], dl	
		mov eax,1
		
.fin_gc:		
				convencion_C_fin 21
				ret


.error_tabla:
	print_error "Hay un error con la tabla!"
	jmp .fin_gc
